package dk.dashboardFP.interactionElementFramwork.buttons {
	import dk.dashboardFP.utils.DisplayChainTools;
	import dk.dashboardFP.utils.Range;
	import dk.dashboardFP.interactionElementFramwork.InteractionElementView;
	import dk.dashboardFP.interactionElementFramwork.InteractionElementViewEvent;

	import flash.display.DisplayObject;
	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	/**
	 * @author jk
	 */
	public class AbstractDraggableButton extends AbstractButton {
		private var _rectDraggable : Rectangle;
		private var _bDraggingDisabled : Boolean=false;
		private var _rangeDrag : Range;
		private var _bDragging : Boolean = false;

		public function AbstractDraggableButton(oIEV : InteractionElementView, rectDraggable:Rectangle=null) {
			_rectDraggable = rectDraggable;
			
			if (!_rectDraggable) {
				_rectDraggable=new Rectangle(0, 0, 150, 0);
			}
			
			_rangeDrag=new Range(_rectDraggable.x, _rectDraggable.width);
			
			super(oIEV);
			setupDraggable();
		}
		
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// enable disable
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		public function disableDragging() : void {
			_bDraggingDisabled=true;
		}
		
		public function enableDragging() : void {
			_bDraggingDisabled=false;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// drag contol
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		
		private function setupDraggable() : void {
			
			//::
			// place handle within rect 
			_doIEV.x = _rectDraggable.x;
			_doIEV.y = _rectDraggable.y;
		}

		override protected function onMouseDownView(event : InteractionElementViewEvent) : void {
			super.onMouseDownView(event);
			
			//::
			// escape if disabled 
			if (_bDraggingDisabled || bDisabled) {
				return;
			}

			_bDragging=true;
			dispatchEvent(new DraggableButtonEvent(DraggableButtonEvent.STARTING_DRAG));
			
			//::
			// update range 
			_rangeDrag.nMinPosition = _rectDraggable.x;
			_rangeDrag.nMaxPosition = _rectDraggable.width;
			
			//::
			// init dragging 
			
			_doIEV.startDrag(false, _rectDraggable);
			
			_doIEV.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true);
			_doIEV.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp, false, 0, true);
		}
		
		private function onMouseUp(event : MouseEvent) : void {
			
			IEventDispatcher(event.target).removeEventListener(event.type, arguments["callee"]);
			
			if (!_doIEV) {
				return;
			}
			
			if (!_doIEV.stage) {
				return;
			}

			_doIEV.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			
			_bDragging=false;
			dispatchEvent(new DraggableButtonEvent(DraggableButtonEvent.ENDING_DRAG));
			
			if (!DisplayChainTools.get_bIsChildOf(event.target as DisplayObject, _doIEV)) {
				_doIEV.mouseUp();
			}
			
			_doIEV.stopDrag();
			
		}

		override public function set x(oNewValue : Number) : void {
			if (!_bDragging) {
				super.x = oNewValue;
			}
		}

		override protected function onMouseOutView(event : InteractionElementViewEvent) : void {
			if (!_bDragging) {
				super.onMouseOutView(event);
			}
		}
		
		public function setPositionByRate(nRate : Number) : void {
			_doIEV.x = _rangeDrag.getPosition(nRate);
		}

		private function onMouseMove(event : MouseEvent) : void {
			dispatchEvent(new DraggableButtonEvent(DraggableButtonEvent.DRAGGED));
		}
		
		public function get nDragPositionRate() : Number { 
			return _rangeDrag.getRate(_doIEV.x); 
		}
		
		public function get rectDraggable() : Rectangle {
			return _rectDraggable;
		}
		
		public function get bDragging() : Boolean {
			return _bDragging;
		}
		
		public function get bDraggingDisabled() : Boolean {
			return _bDraggingDisabled;
		}
	}
}
